package com.qf.smsplatform.controller.advice;
/*2021/11/3*/

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.smsplatform.annotions.IgnoreLog;
import com.qf.smsplatform.annotions.LogOperationAnno;
import com.qf.smsplatform.pojo.MyAuthUser;
import com.qf.smsplatform.pojo.TLogbean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @YuTao
 */
@Aspect
@Component
public class LogAdvice {

    private ObjectMapper objectMapper;
    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    //定义切入点表达式-->方法的全限定名称的类似于正则的写法
    //修饰符 返回值 包.类.方法名（参数）异常
    //public void com.qf.controller.xxxcontroller.selectAll(String userName) throw Exception
    @Pointcut("execution(* com.qf.smsplatform..controller.*Controller.*(..))")
    public void pointCut(){
    }
    @Around("pointCut()")
    public Object processLog(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        System.out.println("我是日志的切入点：：："+signature.toString());//切入点的全限定名称
        Object target = joinPoint.getTarget();//获取到当前方法所在的controller类对象
        Method method = signature.getMethod();//正在执行的方法
        Object[] args = joinPoint.getArgs();//获取传递的参数
        //获取类上边的自定义注解，目的是为了知道当前是什么操作
        Object proceed = joinPoint.proceed();//获取原始结果
        String[] parameterNames = signature.getParameterNames();//获取方法中的参数名

        IgnoreLog ignoreLog = method.getAnnotation(IgnoreLog.class);
        if (ignoreLog != null) {
            //带有这个注解的不记录日志
            return proceed;
        }

            TLogbean tLogbean=new TLogbean();//记录日志的对象
        LogOperationAnno operationAnno = method.getAnnotation(LogOperationAnno.class);
        if (operationAnno != null) {
            String oper = operationAnno.value();//获取到介绍
            tLogbean.setOper(oper);
        }
        tLogbean.setAccessDate(new Date());//设置访问的时间
        //设置参数的
        if (parameterNames != null) {//将参数和值组合起来放在map中
            Map map=new HashMap();
            for (int i = 0; i < parameterNames.length; i++) {
                String parameterName = String.valueOf(parameterNames);//获取每个参数的名字
                Object arg = args[i];//参数的值，可能是一个对象
                map.put(parameterName, arg);

            }
            tLogbean.setParams(objectMapper.writeValueAsString(map));;
        }

        //记录访问的用户
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal != null) {
            Long id = ((MyAuthUser) principal).getId();
            tLogbean.setUserId(id);//设置访问用户的id
        }
        tLogbean.setResult(objectMapper.writeValueAsString(proceed));
        System.out.println("访问记录："+tLogbean);
        return proceed;//返回原始结果
    }

}
